package pl.prv.polanie.client.widgets.schedule.widgets;

import pl.prv.polanie.client.widgets.schedule.ScheduleUtil;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.EventPreview;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Widget;

public abstract class DraggableElement extends Composite implements SourcesDraggingEvents {
//	private static final String STYLE_DRAGGABLE_ELEMENT = "my-DraggableElement";
	
	
	private EventPreview draggingEP = null;

	private DraggingListenerCollection draggingListeners = null;
	
	private int startY;
	
	public DraggableElement() {
		setupDraggingEP();
	}
	

	
	private void setupDraggingEP() {
		draggingEP = new EventPreview() {
			public boolean onEventPreview(Event evt) {
				
				switch (DOM.eventGetType(evt)) {
				case Event.ONMOUSEUP:
//					draggableInProgress = false;
//					Planner.log("DraggableElement.setDraggingEP koniec przeciagania");
					runOnMouseUpWhileDragging(evt);
					break;
				case Event.ONMOUSEMOVE:
//					int x = DOM.eventGetClientX(evt)
//						- DOM.getAbsoluteLeft(getElement())
//						+ DOM.getElementPropertyInt(getElement(), "scrollLeft")
//						+ Window.getScrollLeft();
					
					DraggableZone parentDZ = getParentDraggableZone();
					
					//TODO tutaj poprawcowac z przceiaganiem do gory
					int xOverDZ = ScheduleUtil.getEventXOverWidget(parentDZ, evt);
					int yOverDZ = ScheduleUtil.getEventYOverWidget(parentDZ, evt);
					
					
					int x = DOM.eventGetClientX(evt);
					int y = DOM.eventGetClientY(evt);
					
					draggingListeners.fireOnDragging(getInstance(), x, y-startY, startY);
					runOnMouseMove();
					break;
				case Event.ONKEYDOWN:
					char keyCode = (char)DOM.eventGetKeyCode(evt);
					boolean ctrlPressed = evt.getCtrlKey();
					onKeyDown(keyCode, ctrlPressed);
				default:
					break;
				}
				return false;
			}

		};
	}

	/**
	 * Wlacza tryb draggowania. Zapamietuje startowa pozycje Y. (od gory ekranu)
	 * 
	 * Y powinno byc od gory kontrolki draggableElement.
	 */
	protected void setDraggingOn(int startY) {
			this.startY = startY;
			DOM.addEventPreview(draggingEP);
			runOnStartDragging();
		
	}

	
	/**
	 * @param evt
	 */
	public void runOnMouseUpWhileDragging(Event evt) {
		DOM.removeEventPreview(draggingEP);
		
		int left = DOM.eventGetClientX(evt) + Window.getScrollLeft();
		int top = DOM.eventGetClientY(evt) + Window.getScrollTop();
		runOnDrop(left, top);
	}

	
	/**
	 * Metoda uruchamiana w momencie zakonczenia przeciagania konytolki.
	 */
	protected void runOnDrop(int left, int top) {

	}
	
	protected void runOnStartDragging() {}
	
	protected void onKeyDown(char c, boolean ctrlPressed) {}
	
	protected void runOnMouseMove() {}

	
	protected void onMouseMove(int x, int y) {}

	private DraggableElement getInstance() {
		return this;
	}
	
	public void addDraggingListener(DraggingListener listener) {
		if (draggingListeners == null) {
			draggingListeners = new DraggingListenerCollection();
		}
		draggingListeners.add(listener);
	}
	
	public void removeDraggingListener(DraggingListener listener) {
		if (draggingListeners != null) {
			draggingListeners.remove(listener);
		}
	}

	public void setStartY(int startY) {
		this.startY = startY;
	}
	
	public DraggableZone getParentDraggableZone() {
		
		Widget w = getParent();
		
//		Planner.log("DraggableElement.getParentDraggableZone: " + "111111 " + w);
		
		while (w != null && !(w instanceof DraggableZone)) {
			w = w.getParent();
		}
		
		return (DraggableZone)w;
	}

}

